#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <algorithm>

// 抽象迭代器模板，实现了迭代器接口的最小要求
template <typename T>
class myIter {
    public:
    virtual void First() = 0;      // 指向容器中的第一个元素
    virtual void Next() = 0;       // 指向容器中的下一个元素
    virtual bool IsDone() = 0;     // 是否遍历完
    virtual T& CurrentItem() = 0;  // 获取当前元素
    virtual ~myIter() {}           // 做父类时析构函数应该为虚函数
};

// 抽象容器类模板
template <typename T>
class myCotainer {
    public:
    virtual myIter<T>* CreateIterator() = 0;  // 创建迭代器
    virtual T& getItem(int Index) = 0;        // 获取当前元素
    virtual int getSize() = 0;                // 获取容器中的元素数量
    virtual ~myCotainer() {}                  // 做父类时析构函数应该为虚函数
};

//具体迭代器模板，为简单起见，本迭代器针对的是大小为10个元素的数组
template <typename T> 
class myVectorIter : public myIter<T> {
    public:
    myVectorIter(myCotainer<T>* tmpc) : myvector_(tmpc) {
        m_current_ = 0;
    }

    virtual void First() {
        m_current_ = 0;  // 容器（数组）中的第一个元素下标为0
    }

    virtual void Next() {
        m_current_++;    // 下标+1,表示数组的下一个元素
    }

    virtual bool IsDone() {
        if(m_current_ >= myvector_->getSize()) {
            return true;
        }
        return false;
    }

    virtual T& CurrentItem() {
        return myvector_->getItem(m_current_);
    }

    private:
    myCotainer<T>* myvector_;
    int m_current_;  // 记录数组的当前下标（迭代器在当前容器中的位置）
};

// 具体容器类，实现抽象容器接口，负责储存、管理元素，并提供创建迭代器的功能
template <typename T>
class myVector : public myCotainer<T> {
    public:
    myVector() {
        for(int i = 0; i < 10;i++) {
            m_elem_[i] = i;
        }
    }
    virtual myIter<T>* CreateIterator() {
        // 工厂模式，注意实参传递进去的是该容器的指针this
        return new myVectorIter<T>(this); // 要考虑在哪释放的问题
    }

    virtual T& getItem(int Index) {
        return m_elem_[Index];
    }

    virtual int getSize() {
        return 10;
    }
    private:
    // 为了简化代码，将容器实现为固定装入10个元素的数组
    T m_elem_[10];
};

// 使用具体迭代器（非多态机制）：直接使用具体迭代器，性能更优，适合简单的遍历场景，因为它避免了多态引入的额外开销
void test1() {
    myCotainer<int>* pcontainer = new myVector<int>();
    myVectorIter<int> iter(pcontainer);
    // 遍历容器中的元素
    for(iter.First();!iter.IsDone();iter.Next()) {
        std::cout << iter.CurrentItem() << std::endl;
    }
    // 释放资源
    delete pcontainer;
}

void test2() {
    myCotainer<int>* pcontainer = new myVector<int>();
    myIter<int>* iter = pcontainer->CreateIterator();
    // 遍历容器中的元素
    for(iter->First();!iter->IsDone();iter->Next()) {
        std::cout << iter->CurrentItem() << std::endl;
    }
    // 释放资源
    delete pcontainer;
    delete iter;
}

int main () {
    std::cout << "hello iterator pattern!!!" << std::endl;
    // test1();
    test2();
    return 0;
}